import { _decorator, Node, v3, Vec3, Vec2 } from 'cc';
import { GlobalEnum } from '../../../Init/Config/GlobalEnum';
import { GlobalTmpData } from '../../../Init/Config/GlobalTmpData';
import EventManager from '../../../Init/Managers/EventManager';
import { EventTypes } from '../../../Init/Managers/EventTypes';
import GlobalPool from '../../../Init/Tools/GlobalPool';
import { MappingObj } from './MappingObj';
import { ZombieAnim } from './ZombieAnim';
const { ccclass, property } = _decorator;

@ccclass('MappingZombie')
export class MappingZombie extends MappingObj {
    //------旋转
    public _rotVec = v3();
    //目标弧度
    public _toRadianY = 0;
    //初始弧度
    public _curRadianY = -Math.PI * 0.5;
    //旋转方向 
    public _rotDirec = 1;
    //旋转速度
    public _rotSpd = Math.PI * 4;

    public curState: GlobalEnum.ZombieState = null;
    public anim: ZombieAnim = null;
    public effectsLayer: Node = null;

    public init() {
        this.anim = this.node.getComponentInChildren(ZombieAnim);
        this.effectsLayer = this.node.getChildByName('effects');
        this.updateProp();
        //初始角度
        this._curRadianY = this._toRadianY;
        this._rotVec.set(0, this._curRadianY * 57.3, 0);
        this.node.eulerAngles = this._rotVec;
        //
        EventManager.on(EventTypes.RoleEvents.ShowSurprise, this.onShowSurprise, this);
        EventManager.on(EventTypes.RoleEvents.ShowProtected, this.onShowProtected, this);
    }
    public update(dt: any): void {
        this.updateProp();
        this.rotation(dt);
    }

    public reset(): void {
        EventManager.off(EventTypes.RoleEvents.ShowSurprise, this.onShowSurprise, this);
        EventManager.off(EventTypes.RoleEvents.ShowProtected, this.onShowProtected, this);
        GlobalPool.putAllChildren(this.effectsLayer);
    }

    public updateProp(): void {
        //回收
        if (!this.mappingProps.node.active) {
            GlobalPool.put(this.node);
            return;
        }
        //位置
        this.tmpP.x = this.mappingProps.node.position.x;
        if (this.curState != null) {
            if (this.curState == GlobalEnum.ZombieState.Born || this.curState == GlobalEnum.ZombieState.Atk ||
                this.curState == GlobalEnum.ZombieState.Win) {
                this.tmpP.y = this.mappingProps.node[GlobalEnum.ExtralProp.jumpHight] || 0;
            } else {
                this.tmpP.y = 0;
            }
            this.tmpP.z = -this.mappingProps.node.position.y;
            this.node.setPosition(this.tmpP.multiplyScalar(this.s3d));
        } else {
            this.tmpP.y = this.node.position.y;
            this.tmpP.z = -this.mappingProps.node.position.y;
            this.node.setPosition(this.tmpP.multiply3f(this.s3d, 1, this.s3d));
        }

        //旋转
        const rot: Vec2 = this.mappingProps.node[GlobalEnum.ExtralProp.curLineVec2d];
        this.calRotation(Math.atan2(rot.y, rot.x));

        //状态切换
        if (this.curState != this.mappingProps.state && this.mappingProps.state != null) {
            this.curState = this.mappingProps.state;
            if (!this.anim) {
                this.anim = this.node.getComponentInChildren(ZombieAnim);
            }
            switch (this.curState) {
                case GlobalEnum.ZombieState.Born:
                    this.anim.playAnim(GlobalEnum.ZombieClips.Born);
                    break;
                case GlobalEnum.ZombieState.Idle:
                    if (GlobalTmpData.Game.isGameRun) {
                        this.anim.playAnim(GlobalEnum.ZombieClips.Scream);
                    } else {
                        this.anim.playAnim(GlobalEnum.ZombieClips.Idle);
                    }
                    break;
                case GlobalEnum.ZombieState.Run:
                    this.anim.playAnim(GlobalEnum.ZombieClips.Run);
                    break;
                case GlobalEnum.ZombieState.Crawl:
                    this.anim.playAnim(GlobalEnum.ZombieClips.Crawl);
                    break;
                case GlobalEnum.ZombieState.Win:
                    this.anim.playAnim(GlobalEnum.ZombieClips.Jump);
                    break;
                case GlobalEnum.ZombieState.Death:
                    this.anim.playAnim(GlobalEnum.ZombieClips.Death);
                    break;
                case GlobalEnum.ZombieState.Atk:
                    this.anim.playAnim(GlobalEnum.ZombieClips.Jump);
                    break;
                default:
                    break;
            }
        }
    }
    //旋转3d
    public rotation(dt) {
        if (this._curRadianY !== this._toRadianY) {
            let step = this._rotSpd * dt;
            if (step > Math.abs(this._curRadianY - this._toRadianY)) {
                this._curRadianY = this._toRadianY;
            } else {
                step *= this._rotDirec;
                this._curRadianY += step;
            }
            this._rotVec.set(0, this._curRadianY * 57.3, 0);
            this.node.eulerAngles = this._rotVec;
        }
    }

    //根据目标旋转角度计算出旋转方式-弧度计算
    public calRotation(r: number) {
        this._toRadianY = r;
        //1.0 将当前角色角度+目标角度转换到360之内-弧度计算
        const pi = Math.PI;
        if (this._toRadianY < 0) {
            this._toRadianY += pi * 2;
        }
        this._curRadianY = this._curRadianY % (pi * 2);
        if (this._curRadianY > pi * 2) {
            this._toRadianY -= pi * 2;
        } else if (this._curRadianY < 0) {
            this._toRadianY += pi * 2;
        }
        //2.0 判断差值范围
        let sub = this._toRadianY - this._curRadianY;
        if (sub > pi) {
            //反向
            this._curRadianY += pi * 2;
            this._rotDirec = -1;
        } else if (sub < -pi) {
            //反向
            this._toRadianY += pi * 2;
            this._rotDirec = 1;
        } else if (sub > 0) {
            this._rotDirec = 1;
        } else if (sub < 0) {
            this._rotDirec = -1;
        }
    }

    public onShowSurprise() {
        if (!this.anim) return;
        if (this.curState == GlobalEnum.ZombieState.Idle) {
            this.anim.playAnim(GlobalEnum.ZombieClips.Surprise, true, 1, () => {
                this.anim.playAnim(GlobalEnum.ZombieClips.Idle);
            });
        }
        //效果2d
        EventManager.emit(EventTypes.EffectEvents.showLvupPropEffect, this.node.worldPosition)
    }

    public onShowProtected(uuid, isShow) {
        if (uuid != this.mappingProps.node.uuid) return;

        let node = this.effectsLayer.getChildByName(GlobalEnum.Effect3dType.ZombieProtected)
        if (isShow) {
            if (!node) {
                let e = GlobalPool.get(GlobalEnum.Effect3dType.ZombieProtected);
                e.setPosition(Vec3.ZERO);
                e.parent = this.effectsLayer;
            }
        } else {
            GlobalPool.put(node);
        }
    }

}

